﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.Web;

namespace AVO
{
    public class AVOFieldIterator : ListFieldIterator
    {
        ContentTypeConfiguration Config;

        private void SetControlMode(Microsoft.SharePoint.WebControls.TemplateContainer tc, SPControlMode mode)
        {
            tc.GetType().GetProperty("ControlMode", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(tc, mode, null);
        }
        private void SetFieldName(Microsoft.SharePoint.WebControls.TemplateContainer tc, string fieldName)
        {
            tc.GetType().GetProperty("FieldName", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(tc, fieldName, null);
        }

        public AVOFieldIterator()
            : base()
        {
        }

        SPContentType m_ContentType;
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            string strctid = this.Page.Request.QueryString["ContentTypeId"];
            string itemid = this.Page.Request.QueryString["ID"];
            m_ContentType = GetContentType(strctid, SPContext.Current.List, itemid);

            Config = new ContentTypeConfiguration(m_ContentType);
            Config.Load(false);
        }

        private SPContentType GetContentType(string strctid, SPList list, string itemID)
        {
            //default content type
            if (string.IsNullOrEmpty(strctid))
                return list.ContentTypes[0];

            if (!string.IsNullOrEmpty(itemID) && list != null)
            {
                SPListItem spli = list.GetItemById(Convert.ToInt32(itemID));
                return spli.ContentType;
            }

            if (!string.IsNullOrEmpty(strctid))
            {
                SPContentTypeId ctid = new SPContentTypeId(strctid);
                if (list != null)
                    return list.ContentTypes[ctid];
                else
                    return SPContext.Current.Web.ContentTypes[ctid];
            }

            return null;
        }

        protected override void CreateChildControls()
        {
            this.Controls.Clear();

            if (this.ControlTemplate == null)
                throw new ArgumentException("Could not find ListFieldIterator control template.");

            for (int i = 0; i < base.Fields.Count; i++)
            {
                SPField field = base.Fields[i];

                if (!IsFieldExcluded(field))
                {
                    TemplateContainer child = new TemplateContainer();
                    this.Controls.Add(child);

                    FieldVisibilityConfig fieldCfg = Config[field.Id];
                    if (fieldCfg != null && fieldCfg.Enabled)
                    {
                        var scriptResult = fieldCfg.ScriptFunction.ExecuteScript(
                            "GetControlMode",
                            HttpContext.Current, SPContext.Current, m_ContentType, field, this);
                        if (scriptResult != null && scriptResult.Count() > 0)
                        {
                            string firstRow = scriptResult.FirstOrDefault();

                            if (!string.IsNullOrEmpty(firstRow))
                            {
                                SPControlMode controlMode = (SPControlMode)Enum.Parse(typeof(SPControlMode), firstRow);
                                SetControlMode(child, controlMode);
                            }
                        }
                        else
                            SetControlMode(child, base.ControlMode);
                    }

                    SetFieldName(child, field.InternalName);
                    this.ControlTemplate.InstantiateIn(child);
                }
            }
        }

        protected override bool IsFieldExcluded(SPField field)
        {
            bool bBaseValue = base.IsFieldExcluded(field);
            if (bBaseValue)
                return true;

            if (field.Hidden)
                return true;
            if (!field.Required && field.ShowInEditForm.HasValue && field.ShowInEditForm.Value == false && this.ControlMode == SPControlMode.Edit)
                return true;
            if (!field.Required && field.ShowInDisplayForm.HasValue && field.ShowInDisplayForm.Value == false && this.ControlMode == SPControlMode.Display)
                return true;
            if (!field.Required && field.ShowInNewForm.HasValue && field.ShowInNewForm.Value == false && this.ControlMode == SPControlMode.New)
                return true;


            FieldVisibilityConfig fieldCfg = Config[field.Id];
            if (fieldCfg != null && fieldCfg.Enabled)
            {
                var scriptResult = fieldCfg.ScriptFunction.ExecuteScript(
                    "GetControlMode",
                    HttpContext.Current, SPContext.Current, m_ContentType, field, this);
                if (scriptResult != null && scriptResult.Count() > 0)
                {
                    string firstRow = scriptResult.FirstOrDefault();

                    if (string.IsNullOrEmpty(firstRow))
                        return true;
                }
            }



            return false;
        }
    }
}
